﻿using System;
using System.Collections.Generic;
using System.Text;

#if NETFX
using System.Web;
#endif

namespace Apewer.Web
{

    /// <summary></summary>
    public partial class ApiProgram
    {

        private static ApiInvoker _invoker = new ApiInvoker() { Logger = new Logger(), Options = new ApiOptions() };

        /// <summary>调用器。</summary>
        public static ApiInvoker Invoker { get => _invoker; }

        /// <summary>API 选项。</summary>
        public static ApiOptions Options { get => _invoker.Options; }

        /// <summary>日志记录器。</summary>
        public static Logger Logger { get => _invoker.Logger; }

        /// <summary>获取或设置 API 入口。</summary>
        public static ApiEntries Entries { get => _invoker.Entries; set => _invoker.Entries = value; }

        private Action _initializer = null;

        /// <summary></summary>
        public ApiProgram(Action initializer = null)
        {
            _initializer = initializer;
        }

    }

    // Listener
    public partial class ApiProgram
    {

        static HttpListener _listener = null;

        /// <summary>在后台启动 Listener，返回错误消息。</summary>
        public static string Listener(string prefix)
        {
            if (_listener != null) return "无法重复启动默认 Listener 实例。";
            _listener = new HttpListener();
            _listener.Prefix = prefix;
            _listener.Action = (context) => _invoker.Invoke(new HttpListenerProvider(context));
            var exception = _listener.Start();
            if (exception != null) return exception.Message();

            return null;
        }

    }

    // Mini
    public partial class ApiProgram
    {

        static MiniServer _mini = null;

        /// <summary>启动 Mini 服务器，返回错误消息。</summary>
        public static string Mini(int port = 80, bool await = true)
        {
            if (_mini != null) return "无法重复启动实例。";
            _mini = new MiniServer();
            _mini.Handler = context => _invoker.Invoke(new MiniProvider(context));
            _mini.Run(port, await);
            return null;
        }

    }

#if NETCORE

    // Kestrel & HTTP.Sys
    public partial class ApiProgram
    {

        static AspNetCoreServer _aspnetcore = null;

        class Startup : AspNetCoreStartup
        {

            public override void OnContext(Microsoft.AspNetCore.Http.HttpContext context)
            {
                if (_invoker == null) return;
                _invoker.Invoke(new AspNetCoreProvider(context));
            }

            public override bool UseCompression => Options == null ? false : Options.AllowCompression;

        }

        /// <summary>启动 Kestrel 服务器。</summary>
        public static void Kestrel(int port = 80)
        {
            if (_aspnetcore != null) return;
            var server = new KestrelServer();
            server.Port = port;
            server.Run<Startup>();
            _aspnetcore = server;
        }

        /// <summary>启动 HTTP.sys 服务器。</summary>
        public static void HttpSys(int port = 80, string ip = null)
        {
            if (_aspnetcore != null) return;
            var server = new HttpSysServer();
            server.Port = port;
            server.Run<Startup>();
            _aspnetcore = server;
        }

    }

#endif

#if NETFX

    // IIS
    public partial class ApiProgram : IHttpHandler, IHttpModule
    {

    #region IHttpHandler

        static bool _initialized = false;

        /// <summary></summary>
        public bool IsReusable { get { return false; } }

        /// <summary></summary>
        public void ProcessRequest(HttpContext context)
        {
            if (!_initialized)
            {
                _initialized = true;
                _initializer?.Invoke();
            }
            _invoker.Invoke(new WebsiteProvider(context));
        }

    #endregion

    #region IHttpModule

        /// <summary></summary>
        public void Dispose() { }

        /// <summary></summary>
        public void Init(HttpApplication application)
        {
            application.PreSendRequestHeaders += (s, e) =>
            {
                // 从 Response 头中移除 Server 和 X-Powered-By 属性。
                var response = application.Response;
                var keys = new List<string>(response.Headers.AllKeys);
                if (keys.Contains("Server")) response.Headers.Remove("Server");
                if (keys.Contains("X-Powered-By")) response.Headers.Remove("X-Powered-By");
            };
        }

        IAsyncResult BeginEventHandler(object sender, EventArgs e, AsyncCallback cb, object extraData)
        {
            return null;
        }

        void EndEventHandler(IAsyncResult ar)
        {
        }

    #endregion

    }

#endif

}
